#include "ModRunFactory.h"
#include <QDebug>

#include "../Output/FactoryOutput.h"

#include "Gof23/Gof_Factory/FactorySimple/FactorySimple.h"
#include "Gof23//Gof_Factory/FactoryMethod/FactoryByd.h"
#include "Gof23//Gof_Factory/FactoryMethod/FactoryBMW.h"
#include "Gof23//Gof_Factory/FactoryMethod/FactoryAudi.h"

//普通工厂模式和工厂方法模式的ModRun（Simple Factory and  Factory Method）
ModRunFactory::ModRunFactory()
{
    //模式名称;
    m_strModelName = "普通工厂 方法模式（Simple Factory and  Factory Method）;";
    //模式描述;
    m_strModelDesc = "1.1、简单工厂模式\r\n"
        "    主要特点是需要在工厂类中做判断，从而创造相应的产品，当增加新产品时，需要修改工厂类。使用简单工厂模式，我们只需要知道具体的产品型号就可以创建一个产品。\r\n"
        "    缺点：工厂类集中了所有产品类的创建逻辑，如果产品量较大，会使得工厂类变的非常臃肿。\r\n"
        "1.2、工厂方法模式\r\n"
        "    定义一个创建对象的接口，其子类去具体现实这个接口以完成具体的创建工作。如果需要增加新的产品类，只需要扩展一个相应的工厂类即可。\r\n"
        "    缺点：产品类数据较多时，需要实现大量的工厂类，这无疑增加了代码量。\r\n"
        ;
}

//初始化显示模式;
void ModRunFactory::InitDisplay()
{
    qDebug() << m_strModelName;
    std::shared_ptr<IOutput> pOutPut = FactoryOutput::GetInstance()->CreateDescOutput();
    if (pOutPut)
    {
        std::initializer_list<QString> outList{ m_strModelName,m_strModelDesc};
        pOutPut->OutPut(outList);
    }
}

//返回模式类型;
EnumModRun ModRunFactory::GetEnum()
{
    return emModRunFactory;
}

//运行模式;
void ModRunFactory::ModRun()
{
    std::shared_ptr<IOutput> pOutPut = FactoryOutput::GetInstance()->CreateRunOutput();
    if (pOutPut)
    {
        std::initializer_list<QString> outListStart{ "========简单工厂模式 start:=======" };
        std::initializer_list<QString> outListEnd{ "========简单工厂模式 end:=======" };
        pOutPut->OutPut(outListStart);

        //简单工厂模式;
        FactorySimple simple;
        std::unique_ptr<InterfaceCar> carByd(simple.CreateCar(emCarByd));
        if (carByd)
        {
            carByd->Run();
        }

        std::unique_ptr<InterfaceCar> carAudi(simple.CreateCar(emCarAudi));
        if (carAudi)
        {
            carAudi->Run();
        }

        std::unique_ptr<InterfaceCar> carBMW(simple.CreateCar(emCarBMW));
        if (carBMW)
        {
            carBMW->Run();
        }

        pOutPut->OutPut(outListEnd);

        std::initializer_list<QString> outListmStart{ "========工厂方法模式 start:=======" };
        std::initializer_list<QString> outListmEnd{ "========工厂方法模式 end:=======" };

        pOutPut->OutPut(outListmStart);
        //工厂方法模式;
        std::unique_ptr<InterfaceCar> carBydm(FactorySimple::CreateCarByd());
        if (carBydm)
        {
            carBydm->Run();
        }

        std::unique_ptr<InterfaceCar> carAudim(FactorySimple::CreateCarAdui());
        if (carAudim)
        {
            carAudim->Run();
        }

        std::unique_ptr<InterfaceCar> carBMWm(FactorySimple::CreateCarBMW());
        if (carBMWm)
        {
            carBMWm->Run();
        }
        pOutPut->OutPut(outListmEnd);
    }

}

InterFaceModRun* ModRunFactory::CreateMe()
{
    return new ModRunFactory();
}
